/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
**     of its contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui>

#include "myglwidget.h"
#include "window.h"

Window::Window(QString filename, QString texDir)
{

    this->file_name = filename;
    this->tex_dir = texDir;

    mainLayout = new QHBoxLayout;
    leftLayout = new QVBoxLayout;

    setLayout(mainLayout);
    mainLayout->addLayout(leftLayout);

    // 如果打开IDX文件，加载列表
    QString file_type = QFileInfo(filename).suffix();
    if(0 == file_type.compare("IDX", Qt::CaseInsensitive)) {
        QFile in(filename);
        if(!in.open(QIODevice::ReadOnly))  return;

        in.seek(40);
        QString suffix = QString::fromUtf8(in.read(4));

        in.seek(72);
        QString prefix = QString::fromUtf8(in.read(4));

        QString file_dir = QFileInfo(filename).absolutePath();
        file_name = file_dir + "/" + prefix + "00001" + suffix;

        listWidget = new QListWidget(this);

        int start_byte = 36128;
        int model_name_length = 32;
        int max_byte = in.size();
        for(int i = 0; i * model_name_length + start_byte < max_byte; ++i)
        {
            // 获取模型索引名
            in.seek(i * model_name_length + start_byte);
            QByteArray raw_str = in.read(model_name_length);
            QTextCodec *codec = QTextCodec::codecForName("Big5");
            QString dec_str = codec->toUnicode(raw_str).trimmed();
            int str_i = dec_str.indexOf(QChar::Null);
            if(-1 != str_i) dec_str.truncate(str_i);

            // 过滤空项
            if(!dec_str.isEmpty()) {
                QString file_id = QString::number(i+1).rightJustified(5, '0');
                QListWidgetItem* item = new QListWidgetItem(listWidget);
                item->setText(dec_str);
                item->setData(Qt::UserRole, QVariant(file_dir + "/" + prefix + file_id + suffix));
                listWidget->addItem(item);
            }
        }

        QLineEdit* lineedit_search = new QLineEdit();
        lineedit_search->setPlaceholderText("搜索...");

        connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)),this, SLOT(changeModel(QListWidgetItem*)));
        connect(lineedit_search, SIGNAL(textChanged(const QString &)),this, SLOT(searchList(const QString &)));

        leftLayout->addWidget(lineedit_search);
        leftLayout->addWidget(listWidget);

        listWidget->setFocusPolicy(Qt::NoFocus);

        lineedit_search->setMaximumWidth(300);
        listWidget->setMaximumWidth(300);
    }

    initDisplay();

}

// 加载显示部分
void Window::initDisplay()
{
    displayLayout = new QHBoxLayout;

    glWidget = new myGLWidget(this,file_name);
    glWidget->setTexDir(tex_dir);

    QString title = "模型文件:  ";
    title.append(file_name);
    setWindowTitle(tr(title.toAscii().data()));

    xSlider = createSlider();
    ySlider = createSlider();
    zSlider = createSlider();
    pushButton_export = new QPushButton("导出");  //新增：模型导出按钮

    connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int)));
    connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int)));
    connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int)));
    connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int)));
    connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int)));
    connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int)));
    connect(pushButton_export, SIGNAL(clicked()), glWidget, SLOT(exportModel()));

    displayLayout->addWidget(glWidget);
    displayLayout->addWidget(xSlider);
    displayLayout->addWidget(ySlider);
    displayLayout->addWidget(zSlider);
    displayLayout->addWidget(pushButton_export);
    mainLayout->addLayout(displayLayout);

    xSlider->setValue(15 * 16);
    ySlider->setValue(345 * 16);
    zSlider->setValue(0 * 16);
    pushButton_export->setMaximumWidth(100);

    glWidget->setFocus();

}

// 重置显示部分
void Window::resetDisplay()
{

    disconnect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int)));
    disconnect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int)));
    disconnect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int)));
    disconnect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int)));
    disconnect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int)));
    disconnect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int)));
    disconnect(pushButton_export, SIGNAL(clicked()), glWidget, SLOT(exportModel()));

    displayLayout->removeWidget(glWidget);
    delete glWidget;

    glWidget = new myGLWidget(this,file_name);
    glWidget->setTexDir(tex_dir);

    QString title = "模型文件:  ";
    title.append(file_name);
    setWindowTitle(tr(title.toAscii().data()));

    displayLayout->insertWidget(0, glWidget);

    connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int)));
    connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int)));
    connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int)));
    connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int)));
    connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int)));
    connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int)));
    connect(pushButton_export, SIGNAL(clicked()), glWidget, SLOT(exportModel()));

    glWidget->setFocus();

}

QSlider *Window::createSlider()
{
    QSlider *slider = new QSlider(Qt::Vertical);
    slider->setRange(0, 360 * 16);
    slider->setSingleStep(16);
    slider->setPageStep(15 * 16);
    slider->setTickInterval(15 * 16);
    slider->setTickPosition(QSlider::TicksRight);
    return slider;
}
//! [2]

void Window::keyPressEvent(QKeyEvent *e)
{
    if (e->key() == Qt::Key_Escape)
        close();
    switch ( e->key() ){
    case Qt::Key_Q:
        glWidget->frameIndex++;
        if(glWidget->myply->getFrameNum()<=glWidget->frameIndex)
            glWidget->frameIndex=0;
        glWidget->update();
        break;
    case Qt::Key_W:
        glWidget->offset_y+=0.1;
        glWidget->update();
        break;
    case Qt::Key_S:
        glWidget->offset_y-=0.1;
        glWidget->update();
        break;
    case Qt::Key_A:
        glWidget->offset_x-=0.1;
        glWidget->update();
        break;
    case Qt::Key_D:
        glWidget->offset_x+=0.1;
        glWidget->update();
        break;
    }
}

// 切换模型显示
void  Window::changeModel(QListWidgetItem* item)
{
    this->file_name = item->data(Qt::UserRole).toString();
    resetDisplay();

}

// 列表查询
void Window::searchList(const QString &searchText)
{
    for (int i = 0; i < listWidget->count(); ++i) {
           QListWidgetItem *item = listWidget->item(i);
           if (item->text().contains(searchText, Qt::CaseInsensitive)) {
               item->setHidden(false);
           } else {
               item->setHidden(true);
           }
       }
}
